const {prisma, minioClient, mqttClient}=require('./utils.js')

class TalentAuditController{
    /**
     * GET：获取专家修改信息
     * @param {*} req.params.user_id 用户id
     * @returns
     * 500 内部错误
     * 204 无专家修改记录
     * 200 返回专家修改信息
     */
    find(req,res,next){
        var user_id=Number(req.params.user_id)
        prisma.talentAudit.findUnique({
            where:{
                user_id:user_id
            },
            include:{
                level2s:true
            }
        }).then(talent=>{
            if(talent!=null){
                res.send(200,talent)
                next()
            }else{
                res.send(204)
                next()
            }
        }).catch(e=>{
            console.log(e)
            res.send(500)
            next()
        })
    }

    /**
     * PUT：上传头像
     * @param {*} req.body.user_id
     * @param {*} req.body.file
     * @returns
     * 500 内部错误
     * 200 返回头像名
     */
    upload_avatar(req,res,next){
        let user_id=req.params.user_id
        let avatar=req.files.avatar

        var name=user_id+'-'+Date.now()

        minioClient.fPutObject('talent-avatar',name, avatar.path,{'Content-Type':'image/png'}, function(err,objInfo){
            if(err){
                console.log(err)
                res.send(500,{errmsg:'minio存储失败'})
                next()
            }else{
                res.send(200,{name:name})
                next()
            }
        })
    }

    /**
     * POST：注册专家信息
     * @param {*} req.body.user_id 用户id
     * @param {*} req.body.photo 专家照片
     * @param {*} req.body.titles 专家头衔
     * @param {*} req.body.level2s 擅长领域
     * @param {*} req.body.achievements 成果简介
     * @returns
     * 500 内部错误
     * 200 返回专家修改信息
     */
    async register(req,res){
        var ret=await prisma.talentAudit.findUnique({
            where:{user_id:req.body.user_id},
            include:{
                level2s:{
                    select:{id:true}
                }
            }
        })
        if(ret){ //若审核表中已有记录，将记录移出
            await prisma.talentAudit.delete({
                where:{user_id:req.body.user_id}
            })
        }
        //添加新记录
        var level2s={connect:[]}
        req.body.level2s.map(level2=>{
            level2s.connect.push({id:level2})
        })
        req.body.level2s=level2s
        var talent_audit=await prisma.talentAudit.create({
            data:req.body,
            include:{level2s:true}
        })
        res.send(200,talent_audit)
        //通知审核员更新待审核专家数
        mqttClient.publish('/auditor','talent_audit_count',{qos:1})
    }

    /**
     * DELETE：撤回
     * @param {*} req.params.user_id
     * @returns
     * 404 未找到记录
     * 500 内部错误
     * 200 
     */
    async withdraw(req,res){
        var user_id=Number(req.params.user_id)
        try{
            //若审核表中已有记录，将记录移出
            var talent=await prisma.talentAudit.findUnique({where:{user_id:user_id}})
            if(talent==null){
                res.send(404)
            }else{
                await prisma.talentAudit.delete({where:{user_id:user_id}})
                res.send(200)
                //通知审核员更新待审核专家数
                mqttClient.publish('/auditor','talent_audit_count',{qos:1})
            }
        }catch(err){
            res.send(505)
            console.error(err)
        }
    }

    /**
     * GET：审核员获取所有专家修改信息
     * @param {*} 
     * @returns
     * 500 内部错误
     * 204 无专家修改记录
     * 200 返回专家修改信息列表
     * [
     *      {
     *          talentAudit字段,
     *          level2s:["level1name:level2name", ...]
     *      },
     *      ...
     * ]
     */
    findAll(req,res,next){
        prisma.talentAudit.findMany({
            include:{
                user:true,
                level2s:{
                    select:{
                        name:true,
                        level1:{
                            select:{
                                name:true
                            }
                        }
                    }
                }
            }
        }).then(talents=>{
            talents.map(item=>{
                var level2s=[]
                item.level2s.map(level2=>{
                    level2s.push(`${level2.level1.name}:${level2.name}`)
                })
                item.level2s=level2s
            })
            res.send(200,talents)
            next()
        }).catch(err=>{
            res.send(500,err)
            console.log(Date.now().toLocaleString()+': talent_audit.js->findAll')
            console.log(err)
            next()
        })
    }

    /**
     * GET：审核员获取专家修改信息总数
     * /talent_audit/count
     * @param {*} 
     * @returns
     * 500 内部错误
     * 200 count
     */
    async count(req,res){
        try{
            var num=await prisma.talentAudit.count()
            res.send(200,num)
        }catch(e){
            console.error('Error: /talent_audit/count ', e)
            res.send(500)
        }
    }

    /**
     * PATCH：审核通过
     * @param {int} req.params.id 专家审核表id
     * @param {int} req.params.auditor_id 审核专员id
     * @param {string} req.body.message 审核专员留言
     * @returns
     * 500 内部错误
     * 404 无专家修改记录
     * 403 审核员id有误
     * 200 
     */
    async pass(req,res){
        var id=Number(req.params.id)
        var auditor_id=Number(req.params.auditor_id)
        var message=req.body.message
        var talent_audit=await prisma.talentAudit.findUnique({
            where:{id:id},
            include:{level2s:true}
        })
        if(talent_audit==null) res.send(404)

        var auditor=await prisma.user.findUnique({where:{id:auditor_id, auditor:true}})
        if(auditor==null) res.send(403)

        //构建写入Talent表的数据：
        delete talent_audit.id
        var level2s_connections=[]
        talent_audit.level2s.map(level2=>{
            level2s_connections.push({id:level2.id})
        })
        talent_audit.level2s={connect:level2s_connections}
        talent_audit.audit_at=new Date()
        talent_audit.audit_status="PASSED"

        try{
            await prisma.$transaction(async(prisma)=>{
                await prisma.talentAudit.delete({where:{id:id}})
                var talent=await prisma.talent.findUnique({where:{user_id:talent_audit.user_id}})
                if(talent!=null) await prisma.talent.delete({where:{user_id:talent_audit.user_id}})
                talent_audit=await prisma.talent.create({
                    data:talent_audit,
                    include:{
                        level2s:{
                            select:{
                                id:true,
                                name:true,
                                level1:{
                                    select:{
                                        id:true,
                                        name:true
                                    }
                                }
                            }
                        }
                    }
                })
                await prisma.notification.create({
                    data:{
                        user_id:talent_audit.user_id,
                        auditor_id:auditor_id,
                        auditor_name:auditor.name,
                        to_status:'PASSED',
                        type:'TALENT',
                        content:JSON.stringify(talent_audit),
                        message:message
                    }
                })
            })
            res.send(200)
            //通知用户更新用户信息
            mqttClient.publish(`/user/${talent_audit.user_id}`,'userinfo',{qos:1})
            mqttClient.publish(`/user/${talent_audit.user_id}`,'notification_count',{qos:1})
            //通知审核员更新待审核专家数
            mqttClient.publish('/auditor','talent_audit_count',{qos:1})
        }catch(err){
            console.error(err)
            res.send(500)
        }
    }

    /**
     * PATCH：审核驳回
     * /talent_audit/reject/:id/:auditor_id
     * @param {int} req.params.id 专家审核表id
     * @param {int} req.params.auditor_id 审核专员id
     * @param {string} req.body.message 审核专员留言
     * @returns
     * 500 内部错误
     * 404 无专家修改记录
     * 403 审核员id有误
     * 200 
     */
    async reject(req,res){
        var id=Number(req.params.id)
        var auditor_id=Number(req.params.auditor_id)
        var message=req.body.message
        var talent_audit=await prisma.talentAudit.findUnique({
            where:{id:id},
            include:{level2s:true}
        })
        if(talent_audit==null) res.send(404)

        var auditor=await prisma.user.findUnique({where:{id:auditor_id, auditor:true}})
        if(auditor==null) res.send(403)

        try{
            await prisma.$transaction(async(prisma)=>{
                talent_audit=await prisma.talentAudit.delete({
                    where:{id:id},
                    include:{
                        level2s:{
                            select:{
                                id:true,
                                name:true,
                                level1:{
                                    select:{
                                        id:true,
                                        name:true
                                    }
                                }
                            }
                        }
                    }
                })
                talent_audit.audit_at=new Date()
                talent_audit.audit_status="REJECTED"
                await prisma.notification.create({
                    data:{
                        user_id:talent_audit.user_id,
                        auditor_id:auditor_id,
                        auditor_name:auditor.name,
                        to_status:'REJECTED',
                        type:'TALENT',
                        content:JSON.stringify(talent_audit),
                        message:message
                    }
                })
            })
            res.send(200)
            //通知用户更新通知
            mqttClient.publish(`/user/${talent_audit.user_id}`,'notification_count',{qos:1})
            //通知审核员更新待审核专家数
            mqttClient.publish('/auditor','talent_audit_count',{qos:1})
        }catch(err){
            console.error(err)
            res.send(500)
        }
    }
}

module.exports=new TalentAuditController()